#include <array>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>

using Key16 = std::array<uint8_t,16>;

// 从 32 字符 hex 字符串解析出 16 字节 key
Key16 parseKey16(const std::string &hex) {
    if (hex.size() != 32) {
        throw std::invalid_argument("密钥长度应为 32 个十六进制字符");  
    }
    Key16 key;
    for (int i = 0; i < 16; i++) {
        // substr 每两字符 → "A1" 之类
        std::string byteStr = hex.substr(2*i, 2);
        // stoul 支持 base=16，将子串转为 unsigned long，再截为 uint8_t【:contentReference[oaicite:0]{index=0}】
        key[i] = static_cast<uint8_t>( std::stoul(byteStr, nullptr, 16) );
    }
    return key;
}

// 对文件做 循环‑16‑字节 XOR 加密/解密
void xorFile16(const std::string &infile,
               const std::string &outfile,
               const Key16 &key)
{
    std::ifstream fin(infile,  std::ios::binary);
    std::ofstream fout(outfile, std::ios::binary);
    if (!fin)  throw std::runtime_error("无法打开输入文件");  
    if (!fout) throw std::runtime_error("无法打开输出文件");

    uint8_t byte;
    size_t pos = 0;
    // 按字节读，未知行数、任意内容都处理
    while (fin.read(reinterpret_cast<char*>(&byte),1)) {
        // 周期性 XOR：pos % key.size()【:contentReference[oaicite:1]{index=1}】
        uint8_t out = byte ^ key[pos % key.size()];
        fout.write(reinterpret_cast<const char*>(&out),1);
        pos++;
    }
}

int main(int argc, char* argv[]) {
    if (argc != 4) {
        std::cerr << "用法： " << argv[0]
                  << " <输入文件> <输出文件> <32字符十六进制密钥>\n";
        return 1;
    }
    try {
        std::string inFile  = argv[1];
        std::string outFile = argv[2];
        std::string hexKey  = argv[3];

        Key16 key = parseKey16(hexKey);    // 解析为 16 字节数组
        xorFile16(inFile, outFile, key);    // 执行循环‑16‑字节 XOR
        std::cout << "处理完成\n";
    } catch (const std::exception &e) {
        std::cerr << "错误: " << e.what() << "\n";
        return 1;
    }
    return 0;
}
